package demo.hms.user.service.servicelmpl;
import demo.hms.mybatis.entity.User;
import demo.hms.user.dao.UserDao;
import demo.hms.user.service.UserService;
import demo.hms.util.Result;
import demo.hms.util.ResultSubmit;
import demo.hms.util.Toekn;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



@Service
/**
 * 声明式事务注解配置
 *
 * 参数说明：
 * propagation = Propagation.REQUIRED    - 事务传播机制：如果当前存在事务，则加入该事务；
 *                                        如果当前没有事务，则创建一个新的事务（默认值）
 * isolation = Isolation.READ_COMMITTED  - 事务隔离级别：读已提交，防止脏读，允许不可重复读和幻读
 * rollbackFor = Exception.class         - 回滚策略：当方法抛出Exception及其子类异常时触发事务回滚
 *
 * 注意：该注解应作用于需要事务管理的方法或类上，通过AOP代理实现事务控制
 */
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class)

/**
 * 用户服务实现类
 * 提供用户登录、信息查询、用户管理等功能实现
 */
public class UserServiceImpl implements UserService {
    // 第一种注入方式 动态注入 resource通过类去注入
    @Resource
    private UserDao userDao;

    /**
     * 日期格式化工具，用于处理时间相关数据
     * 格式：年-月-日 时:分:秒
     */
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 动态注入 类名
    @Autowired
    Toekn toekn;



    /**
     * 根据用户ID查询用户信息
     * @param userId 用户唯一标识符
     * @return 包含用户查询结果的封装对象
     */
    @Override
    public Result select(String userId) {
        return ResultSubmit.success(userDao.ste(userId));
    }

    /**
     * 用户登录验证方法
     * @param userid 用户登录账号
     * @param userpassword 用户登录密码
     * @param request HTTP请求对象，用于获取会话信息
     * @return 登录结果封装对象：
     *         - 成功：返回用户数据和认证token
     *         - 失败：返回密码错误或未注册提示
     */
    @Override
    public Result login(@RequestBody String userid, String userpassword, HttpServletRequest request) {
        try {
            User user = userDao.ste(userid);
            if (userpassword.equals(user.getUserPassword())) {
                /* 登录成功处理流程：
                 * 1. 创建用户会话
                 * 2. 存储基础用户信息
                 * 3. 生成时间戳和认证token
                 * 4. 返回完整用户数据
                 */
                HttpSession session = request.getSession();
                session.setAttribute("userId",user.getUserId().toString());
                session.setAttribute("userpassword",user.getUserPassword());
                session.setAttribute("userName",user.getUserName());
                session.setAttribute("roleName",user.getRoleName());
                Long time = System.currentTimeMillis();
                session.setAttribute("time",time);
                session.setAttribute("token",toekn.getToken(userid,userpassword,user.getRoleName(),time));
                return ResultSubmit.success(user);
            }else {
                return ResultSubmit.success("密码错误");
            }
        }catch (Exception e){
            if(e.getClass()== NullPointerException.class){
                return ResultSubmit.error("登录失败，用户未注册");
            }else {
                e.printStackTrace();
                return ResultSubmit.fall();
            }
        }
    }

    /**
     * 获取当前登录用户的基本信息
     * @param request HTTP请求对象，用于获取会话信息
     * @return 包含用户ID、用户名、角色名的封装对象
     */
    //重写注解
    @Override
    public Result info(HttpServletRequest request){
        HttpSession session = request.getSession();
        /* 构建用户信息映射表：
         * 从会话中提取核心用户属性
         */
        Map<String, String> map = new HashMap<>();
        map.put("userId", session.getAttribute("userId").toString());
        map.put("userName", session.getAttribute("userName").toString());
        map.put("roleName", session.getAttribute("roleName").toString());
        // todo 系统记录查询并返回房间类型数据
        return ResultSubmit.success(map);
    }

    /**
     * 多条件查询用户列表
     * @param userId 用户ID筛选条件（0表示不限制）
     * @param userName 用户姓名模糊匹配条件
     * @param roleName 角色名称精确匹配条件
     * @return 包含用户列表的封装对象
     */
    //Override重写注解
    @Override
    public Result selectAllUser(String userId, String userName, String roleName){
        List<User> user = userDao.selectAllUser(userId,userName,roleName);
        return ResultSubmit.success(user);

    }

    /**
     * 用户数据格式处理方法
     * @param user 原始用户对象
     * @return 处理后仅包含核心属性的用户对象（用户ID、用户名、角色名）
     */
    //动态注入的实现
    private User re(User user){
        /* 用户数据脱敏处理：
         * 仅保留必要字段，防止敏感信息泄露
         */
        User result = new User();
        result.setUserId(user.getUserId());
        result.setUserName(user.getUserName());
        result.setRoleName(user.getRoleName());
        return result;

    }

    /**
     * 插入用户数据并返回操作结果
     *
     * @param user 待插入的用户对象，需要包含必要字段（注意：方法内部会覆盖userId和createTime字段）
     * @return Result 包含操作状态的结果对象，成功时返回操作影响行数，失败时返回错误信息
     */
    @Override
    public Result insertUser(User user) {
            user.setRoleId(2);
            user.setDeleteId("未删除");
            user.setUserId(Math.abs((int)System.currentTimeMillis()));
            user.setCreateTime(format.format(System.currentTimeMillis()));
            int insertUser1 = userDao.insert(user);
        System.out.println(user);
            //todo 系统记录查询
            if (insertUser1 == 1) {
                System.out.println("数据插入成功");
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResultSubmit.error("数据插入错误,请检查数据是否有误");
            }
            return ResultSubmit.success(insertUser1);
        }

    @Override
    public Result updateUser(User user) {
       int updateUser1 = userDao.update(user);
       user.setUserTableId(null);
        // 设置格式化后的创建时间
        user.setDeleteId("未删除");
        user.setCreateTime(format.format(System.currentTimeMillis()));
        int insertUser1 = userDao.insert(user);
        if (updateUser1 ==1 || insertUser1 == 1 )  {
            System.out.println("数据修改成功");
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultSubmit.error("数据修改失败");
        }
        // 返回标准化成功结果
        return ResultSubmit.success(updateUser1);
    }
    /**
     * 操作用户数据并返回操作结果（具体业务含义需结合上下文）
     *
     * @param userId 被操作用户的ID标识
     * @return Result 包含操作结果的封装对象：
     *         - success: 返回更新成功的记录数
     *         - error: 当更新失败时返回错误信息（自动触发事务回滚）
     */
    @Override
    public Result dabbleUser(String userId){
        // 通过DAO层获取用户实体（需确认ste方法的具体实现）
        User dabbleUser = userDao.ste(userId);
        // 执行用户数据更新操作
        int updateUser1 = userDao.update(dabbleUser);

        // 处理更新结果
        if (updateUser1 == 1)  {
            System.out.println("数据修改成功");
        } else {
            // 更新失败时强制回滚当前事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultSubmit.error("数据修改失败");
        }
        return ResultSubmit.success(updateUser1);
    }
}









